//
//  HJChatMessageManager.m
//  KaiChat
//
//  Created by lx on 2023/10/20.
//

#import "HJChatMessageManager.h"
#import "HJChatMessageModel.h"
#import "HJChatSessionModel.h"
#import "HJChatGroupModel.h"
#import "HJGroupMemberModel.h"
#import "HJIM.h"
#import "HJMessageFileManager.h"

@implementation HJChatMessageManager


- (void)querySendingMessageCompletion:(void (^__nullable)(NSArray *messages))completion {
    NSString * where = [NSString stringWithFormat:@"where %@ is not null ORDER BY %@ desc",bg_sqlKey(@"sessionId"),bg_sqlKey(@"timestamp")];
    [HJChatSessionModel bg_findAsync:[HJChatSessionModel bg_tableName] where:where complete:^(NSArray * _Nullable array) {
        NSMutableArray *messageModels = [NSMutableArray array];
        for (HJChatSessionModel *sessionModel in array) {
            NSString *where = [NSString stringWithFormat:@"where %@=%@",bg_sqlKey(@"msgStatus"),bg_sqlValue(@(HJMessageStatusSending))];
            NSArray *array = [HJChatMessageModel bg_find:[HJChatMessageModel bg_tableNameWithSessionId:sessionModel.sessionId] where:where];
            if (array.count) {
                [messageModels addObjectsFromArray:array];
            }
        }
        if (completion) {
            completion(messageModels);
        }
    }];
}

- (void)loadMessageDatasBySessionId:(NSString*)sessionId pageSize:(NSInteger)pageSize pageNumber:(NSInteger)pageNumber completion:(void (^__nullable)(NSArray *messages))completion {
    
    NSString *tableName = [HJChatMessageModel bg_tableNameWithSessionId:sessionId];
    NSInteger allMessagesCount = [HJChatMessageModel bg_count:tableName where:nil];
    if (pageSize <= 0) {
        pageSize = 20;
    }
    NSRange range = HJMakeRange(allMessagesCount, pageNumber, pageSize);
    [HJChatMessageModel bg_findAsync:tableName range:range orderBy:@"timestamp" desc:YES complete:^(NSArray * _Nullable array) {
        if (completion) {
            completion(array);
        }
    }];
}

- (BOOL)deleteMessageWithMessageModel:(HJChatMessageModel *)messageModel {
    NSString *tableName = [HJChatMessageModel bg_tableNameWithSessionId:messageModel.sessionId];
    NSString *where = [NSString stringWithFormat:@"where %@=%@",bg_sqlKey(@"msgId"),bg_sqlValue(messageModel.msgId)];
    BOOL res = [HJChatMessageModel bg_delete:tableName where:where];
    if (res) {
        [HJMessageFileManager deleteFileWithMessageModel:messageModel];
    }
    return res;
}

- (BOOL)deleteMessagesBySessionId:(NSString*)sessionId messageId:(NSString *)messageId {
    NSString *tableName = [HJChatMessageModel bg_tableNameWithSessionId:sessionId];
    NSString *where = [NSString stringWithFormat:@"where %@=%@",bg_sqlKey(@"msgId"),bg_sqlValue(messageId)];
    return [HJChatMessageModel bg_delete:tableName where:where];
}

- (HJChatMessageModel *)queryMessageBySessionId:(NSString *)sessionId messageId:(NSString *)messageId {
    NSString *tableName = [HJChatMessageModel bg_tableNameWithSessionId:sessionId];
    NSString *where = [NSString stringWithFormat:@"where %@=%@",bg_sqlKey(@"msgId"),bg_sqlValue(messageId)];
    return [HJChatMessageModel bg_find:tableName where:where].firstObject;
}

- (BOOL)isNewMessageBySessionId:(NSString *)sessionId messageId:(NSString *)messageId {
    NSString *tableName = [HJChatMessageModel bg_tableNameWithSessionId:sessionId];
    NSString *where = [NSString stringWithFormat:@"where %@=%@",bg_sqlKey(@"msgId"),bg_sqlValue(messageId)];
    return [HJChatMessageModel bg_count:tableName where:where] == 0;
}

- (void)clearHistoryBySessionId:(NSString*)sessionId completion:(void (^__nullable)(BOOL result))completion {
    NSString *tableName = [HJChatMessageModel bg_tableNameWithSessionId:sessionId];
    [HJChatMessageModel bg_dropAsync:tableName complete:^(BOOL isSuccess) {
        if (completion) {
            completion(isSuccess);
        }
    }];
}

- (HJChatMessageModel *)getSessionLastMessagesBySessionId:(NSString*)sessionId {
    return [HJChatMessageModel bg_find:[HJChatMessageModel bg_tableNameWithSessionId:sessionId] limit:1 orderBy:@"timestamp" desc:YES].lastObject;
}


- (NSString *)getMaxServerMsgIdMessagesBySessionId:(NSString*)sessionId {
    HJChatMessageModel *maxServerMsgIdModel = [HJChatMessageModel bg_find:[HJChatMessageModel bg_tableNameWithSessionId:sessionId] limit:1 orderBy:@"serverMsgId" desc:YES].lastObject;
    return maxServerMsgIdModel.serverMsgId;
}


- (void)loadOfflineMessage {
    TJLog(@"拉取离线消息");
    [HJNetworking.shareNetwork POSTBodyJSON:API_offlineMessage parameters:nil success:^(NSDictionary * _Nonnull responseObject, id  _Nonnull datas) {
        
        dispatch_async_sql_queue(^{
            
            if (![datas isKindOfClass:NSArray.class] || [datas count] <= 0) {
                return;
            }
                        
            NSMutableArray *sessionModels = [NSMutableArray array];
            NSInteger saveError = 0;

            for (NSDictionary *sessionDict in datas) {
                
                NSArray *messages = sessionDict[@"msgs"];
                NSMutableArray *messageModels = [NSMutableArray array];
                NSInteger totalUnReadCount = 0;
                
                
                for (NSDictionary *messageDict in [messages reverseObjectEnumerator]) {
                    
                    NSInteger systemMsgType = [messageDict[@"sys_msg_type"] intValue];

                    HJChatMessageModel *chatMessageModel = [HJChatMessageModel messageModelWithSessionDict:sessionDict messageDict:messageDict];
                    if (!chatMessageModel && systemMsgType != HJChatSystemMsgTypeTransfer) {
                        continue;
                    };
                    
                    if (chatMessageModel.systemMsgType == 400 || chatMessageModel.systemMsgType == 407) {
                        dispatch_async_main_queue(^{
                            [[NSNotificationCenter defaultCenter] postNotificationName:groupSystemNotification object:chatMessageModel];
                        });
                        continue;
                    }
   
                    [HJIM.shareIM.messageManager handleSystemMsg:chatMessageModel];
                    
                    if (chatMessageModel.chatType != HJChatTypeOfficial && chatMessageModel.sessionId.intValue == 0) {
                        continue;
                    }
                    
                    if (isEmptyString(chatMessageModel.content) && (chatMessageModel.messageType == HJMessageTypeText || chatMessageModel.messageType == HJMessageTypeSystem)) {
                        continue;
                    };
                    
                    
                    BOOL isNewMessage = [HJIM.shareIM.messageManager isNewMessageBySessionId:chatMessageModel.sessionId messageId:chatMessageModel.msgId];
                    [chatMessageModel previewLink];

                    if (chatMessageModel.messageType == HJMessageTypeTransfer) {
                        
                        if (chatMessageModel.countedUnreadCount && isNewMessage) {
                            totalUnReadCount = totalUnReadCount + 1;
                        }
                        [chatMessageModel bg_saveOrUpdate];
                        
                    } else if (systemMsgType == HJChatSystemMsgTypeTransfer) {
                        
                        NSDictionary *payInfo = [messageDict[@"content"] mj_JSONObject];
                        NSString *msgId = nil;
                        if ([payInfo isKindOfClass:NSDictionary.class]) {
                            msgId = toString(payInfo[@"msg_id"]);
                        } else {
                            msgId = toString(messageDict[@"association_msg_id"]);
                        }
                        
                        HJChatMessageModel *transferMessageModel = [HJIM.shareIM.messageManager queryMessageBySessionId:toString(messageDict[@"session_id"]) messageId:msgId];
                        transferMessageModel.orderStatus = [payInfo[@"order_status"] intValue];
                        [transferMessageModel bg_saveOrUpdate];
                    } else {
                        if (chatMessageModel.countedUnreadCount && isNewMessage) {
                            totalUnReadCount = totalUnReadCount + 1;
                        }
                    }
                
                    [messageModels addObject:chatMessageModel];
                    [chatMessageModel downloadVoice];
                }
                
                if (messageModels.count == 0) {
                    continue;
                }
                
                if (![HJChatMessageModel bg_saveOrUpdateArray:messageModels]) {
                    saveError += 1;
                    continue;
                }
                
                HJChatMessageModel *firstMessageModel = messageModels.firstObject;
                NSString *sessionId = firstMessageModel.sessionId;
                
                HJChatMessageModel *chatMessageModel = [self getSessionLastMessagesBySessionId:sessionId];
                HJChatSessionModel *chatSessionModel = [HJChatSessionModel sessionModelWithMessageModel:chatMessageModel];
                
                if (!chatSessionModel.sessionId) return;
                
                chatSessionModel.isMute = toString(sessionDict[@"is_mute"]);
                chatSessionModel.isTop = toString(sessionDict[@"is_top"]);
                chatSessionModel.sessionName = sessionDict[@"session_name"];
                chatSessionModel.sessionAvatar = sessionDict[@"session_image"];
                
                if (chatSessionModel.chatType == HJChatTypeSingle) {
                    chatMessageModel.senderAvatar = chatSessionModel.sessionAvatar;
                    chatMessageModel.senderNickname = chatSessionModel.sessionName;
                }
                
                for (HJChatMessageModel *obj in messageModels) {
                    if (obj.messageType == HJMessageTypeNotice) {
                        chatSessionModel.hasNotice = @"1";
                        [chatSessionModel bg_saveOrUpdate];
                    }
                }
                
                chatSessionModel.isSendMsg = @"2";
                chatSessionModel.unReadCount = [NSString stringWithFormat:@"%ld", totalUnReadCount];
                
                HJChatSessionModel *lastSessionModel = [HJIM.shareIM.conversationManager getConversationBySessionId:chatSessionModel.sessionId];
                chatSessionModel.unReadCount = toString(@(lastSessionModel.unReadCount.integerValue + chatSessionModel.unReadCount.integerValue));
                if (chatSessionModel.chatType == HJChatTypeGroup) {
                    chatSessionModel.hasNotice = lastSessionModel.hasNotice;
                }
                [chatSessionModel bg_saveOrUpdate];
                
                if (messages.count) {
                    [[NSNotificationCenter defaultCenter] postNotificationName:receiveOfflineMessageNotification object:@{
                        @"sessionModel": chatSessionModel,
                        @"messages": messageModels
                    }];
                }
                [sessionModels addObject:chatSessionModel];
                [self updateSessionModel:chatSessionModel];
            }
            
            if (saveError == 0) {
                [self comfirmReceiveOfflineMessage];
            }
            [[NSNotificationCenter defaultCenter] postNotificationName:offlineMessageLoadCompleteNotification object:sessionModels];
        });
        
    } failure:^(NSError * _Nonnull error) {
    }];
}


- (void)loadNewsOfflineMessage {
    TJLog(@"拉取news离线消息");
    [HJNetworking.shareNetwork GET:API_newsOfflineMessage parameters:nil success:^(NSDictionary * _Nonnull responseObject, id  _Nonnull data) {
        
        NSArray *datas = data[@"list"];
        if (![datas isKindOfClass:NSArray.class])  {
            return;
        };
        
        dispatch_async_sql_queue(^{
            
            NSMutableArray *sessionModels = [NSMutableArray array];
            NSInteger saveError = 0;
            for (NSDictionary *sessionDict in datas) {
                
                NSArray *messages = sessionDict[@"msgs"];
                NSMutableArray *messageModels = [NSMutableArray array];
                NSInteger totalUnReadCount = 0;
                for (NSDictionary *messageDict in messages) {
                    HJChatMessageModel *chatMessageModel = [HJChatMessageModel messageModelWithSessionDict:sessionDict messageDict:messageDict];
                    if (!chatMessageModel) {
                        continue;
                    };
                    
                    [chatMessageModel previewLink];
                    BOOL isNewMessage = [HJIM.shareIM.messageManager isNewMessageBySessionId:chatMessageModel.sessionId messageId:chatMessageModel.msgId];
                    if (chatMessageModel.countedUnreadCount && isNewMessage) {
                        totalUnReadCount = totalUnReadCount + 1;
                    }
                    [messageModels addObject:chatMessageModel];
                }
          
                if (messageModels.count == 0) {
                    continue;
                }
                
                if (![HJChatMessageModel bg_saveOrUpdateArray:messageModels]) {
                    saveError += 1;
                    continue;
                }
                
                NSString *sessionId = getOfficiaSessionId(sessionDict[@"session_id"]);
                HJChatMessageModel *chatMessageModel = [self getSessionLastMessagesBySessionId:sessionId];
                
                HJChatSessionModel *chatSessionModel = [HJChatSessionModel sessionModelWithMessageModel:chatMessageModel];
                chatSessionModel.isMute = toString(sessionDict[@"is_mute"]);
                chatSessionModel.isTop = toString(sessionDict[@"is_top"]);
                chatSessionModel.sessionName = sessionDict[@"session_name"];
                chatSessionModel.sessionAvatar = sessionDict[@"session_image"];
                chatSessionModel.isSendMsg = @"2";
                chatSessionModel.unReadCount = [NSString stringWithFormat:@"%ld", totalUnReadCount];
                chatSessionModel.receiveId = HJUserInfo.userId;
                chatSessionModel.receiveName = HJUserInfo.nickname;
                
                HJChatSessionModel *lastSessionModel = [HJIM.shareIM.conversationManager getConversationBySessionId:chatSessionModel.sessionId];
                chatSessionModel.unReadCount = toString(@(lastSessionModel.unReadCount.integerValue + chatSessionModel.unReadCount.integerValue));
                if (chatSessionModel.chatType == HJChatTypeGroup) {
                    chatSessionModel.hasNotice = lastSessionModel.hasNotice;
                }
                [chatSessionModel bg_saveOrUpdate];
                
                if (messages.count) {
                    [[NSNotificationCenter defaultCenter] postNotificationName:receiveOfflineMessageNotification object:@{
                        @"sessionModel": chatSessionModel,
                        @"messages": messageModels
                    }];
                }
                
                [sessionModels addObject:chatSessionModel];
                [self updateSessionModel:chatSessionModel];
            }
            
            if (saveError == 0) {
                [self comfirmReceiveNewsOfflineMessage:[data[@"max_seq_id"] integerValue]];
            }
            
            [[NSNotificationCenter defaultCenter] postNotificationName:offlineMessageLoadCompleteNotification object:sessionModels];
        });
    } failure:^(NSError * _Nonnull error) {
    }];
}

- (void)updateSessionModel:(HJChatSessionModel *)chatSessionModel {
        
    if (chatSessionModel.chatType == HJChatTypeOfficial) {
        
        if (isEmptyString(chatSessionModel.sessionName) || isEmptyString(chatSessionModel.sessionAvatar)) {
            [HJIM.shareIM.chatManager queryOfficialAccountCompletion:^(NSArray * _Nullable datas) {
                
                for (HJChatSessionModel *model in datas) {
                    if ([model.sessionId isEqualToString:chatSessionModel.sessionId]) {
                        
                        chatSessionModel.sessionName = model.sessionName;
                        chatSessionModel.sessionAvatar = model.sessionAvatar;
                        [chatSessionModel bg_saveOrUpdateAsync:^(BOOL isSuccess) {}];
                        
                        [[NSNotificationCenter defaultCenter] postNotificationName:updateConversationInfoNotification object:chatSessionModel];
                        break;
                    }
                }
            }];
        }

    } else {
        
        if (isEmptyString(chatSessionModel.sessionAvatar) || isEmptyString(chatSessionModel.sessionName) || isEmptyString(chatSessionModel.sessionUserd)) {
            
            [HJIM.shareIM.conversationManager loadConversatioInfoWithSessionId:chatSessionModel.sessionId type:chatSessionModel.chatType completion:^(HJChatSessionModel * _Nonnull sessionModel) {
                
                chatSessionModel.sessionName = sessionModel.sessionName;
                chatSessionModel.sessionAvatar = sessionModel.sessionAvatar;
                chatSessionModel.sessionUserd = sessionModel.sessionUserd;
                chatSessionModel.isTop = sessionModel.isTop;
                chatSessionModel.isMute = sessionModel.isMute;
                [chatSessionModel bg_saveOrUpdateAsync:^(BOOL isSuccess) {}];
                [[NSNotificationCenter defaultCenter] postNotificationName:updateConversationInfoNotification object:chatSessionModel];
            }];
        }
    }
   
}

- (void)handleSystemMsg:(HJChatMessageModel *)messageModel {
    
    if (messageModel.systemMsgType == HJChatSystemMsgTypeKickOutGroup ||
        messageModel.systemMsgType == HJChatSystemMsgTypePostGroupNotice ||
        messageModel.systemMsgType == HJChatSystemMsgTypeAddGroupManager ||
        messageModel.systemMsgType == HJChatSystemMsgTypeRemoveGroupManager ||
        messageModel.systemMsgType == HJChatSystemMsgTypeJoinGroup ||
        messageModel.systemMsgType == HJChatSystemMsgTypeModifyGroupName ||
        messageModel.systemMsgType == HJChatSystemMsgTypeTransferGroup
        ) {
        
        dispatch_async_main_queue(^{
            [[NSNotificationCenter defaultCenter] postNotificationName:groupSystemNotification object:messageModel];
        });
        
        if (messageModel.systemMsgType == HJChatSystemMsgTypeKickOutGroup) {
            
            if ([messageModel.senderId isEqualToString:HJUserInfo.userId]) return;
            
            HJChatGroupModel *groupModel = [HJIM.shareIM.groupManager queryGroupInfoByGroupId:messageModel.sessionId];
            groupModel.groupStatus = 2;
            [groupModel bg_saveOrUpdate];
            
        } else if (messageModel.systemMsgType == HJChatSystemMsgTypeAddGroupManager) {
            
            NSDictionary *systemMsgDict = [messageModel.msg mj_JSONObject];
            HJChatGroupModel *groupModel = [HJIM.shareIM.groupManager queryGroupInfoByGroupId:messageModel.sessionId];
            
            NSArray *executedUsers = systemMsgDict[@"be_executed"];
            
            for (NSDictionary *user in executedUsers) {
                NSString *where = [NSString stringWithFormat:@"where %@=%@", bg_sqlKey(@"userId"),bg_sqlValue(user[@"user_id"])];
                HJGroupMemberModel *groupMemberModel = [HJGroupMemberModel bg_find:[HJGroupMemberModel bg_tableNameWithGroupId:groupModel.groupId] where:where].lastObject;
                groupMemberModel.role = 2;
                [groupMemberModel bg_saveOrUpdate];
            }
        } else if (messageModel.systemMsgType == HJChatSystemMsgTypeRemoveGroupManager) {
            
            NSDictionary *systemMsgDict = [messageModel.msg mj_JSONObject];
            HJChatGroupModel *groupModel = [HJIM.shareIM.groupManager queryGroupInfoByGroupId:messageModel.sessionId];
            
            NSArray *executedUsers = systemMsgDict[@"be_executed"];
            
            for (NSDictionary *user in executedUsers) {
                NSString *where = [NSString stringWithFormat:@"where %@=%@", bg_sqlKey(@"userId"),bg_sqlValue(user[@"user_id"])];
                HJGroupMemberModel *groupMemberModel = [HJGroupMemberModel bg_find:[HJGroupMemberModel bg_tableNameWithGroupId:groupModel.groupId] where:where].lastObject;
                groupMemberModel.role = 3;
                [groupMemberModel bg_saveOrUpdate];
            }
        } else if (messageModel.systemMsgType == HJChatSystemMsgTypeModifyGroupName) {
            
            NSDictionary *systemMsgDict = [messageModel.msg mj_JSONObject];
            HJChatGroupModel *groupModel = [HJIM.shareIM.groupManager queryGroupInfoByGroupId:messageModel.sessionId];
            messageModel.groupName = systemMsgDict[@"new_room_name"];
            groupModel.name = messageModel.groupName;
            [groupModel bg_saveOrUpdate];
        } else if (messageModel.systemMsgType == HJChatSystemMsgTypePostGroupNotice) {
            
            NSDictionary *systemMsgDict = [messageModel.msg mj_JSONObject];
            
            HJChatGroupModel *groupModel = [HJIM.shareIM.groupManager queryGroupInfoByGroupId:messageModel.sessionId];
            
            NSMutableDictionary *groupNoticeInfo = [NSMutableDictionary dictionary];
            [groupNoticeInfo setValue:@(messageModel.timestamp.integerValue / 1000) forKey:@"publish_time"];
            [groupNoticeInfo setValue:messageModel.senderAvatar forKey:@"avatar"];
            [groupNoticeInfo setValue:messageModel.senderNickname forKey:@"nickname"];
            
            NSMutableDictionary *dict = [NSMutableDictionary dictionary];
            NSDictionary *extensionDict = groupModel.extension.mj_JSONObject;
            [dict addEntriesFromDictionary:extensionDict];
            
            [dict setValue:groupNoticeInfo forKey:groupNoticeInfoKey];
            
            groupModel.extension = dict.mj_JSONString;
            groupModel.notice = systemMsgDict[@"notice_content"];
            
            NSString *operatorUserId = toString(systemMsgDict[@"operator"][@"user_id"]);
            if (!TJIM_isSelf(operatorUserId)) {
                groupModel.showNotice = @1;
            }
            
            [groupModel bg_saveOrUpdate];
        }
        
        [[NSNotificationCenter defaultCenter] postNotificationName:systemHandleCompleteNotification object:messageModel];
        
    }
    
}


- (void)comfirmReceiveOfflineMessage {
    [HJNetworking.shareNetwork POSTBodyJSON:API_receiveOfflineMessage parameters:nil success:^(NSDictionary * _Nonnull responseObject, id  _Nonnull data) {
    } failure:^(NSError * _Nonnull error) {
    }];
}

- (void)comfirmReceiveNewsOfflineMessage:(NSInteger)max_seq_id {
    [HJNetworking.shareNetwork POSTBodyJSON:API_readNewsOfflineMessage parameters:@{
        @"max_seq_id": @(max_seq_id)
    } success:^(NSDictionary * _Nonnull responseObject, id  _Nonnull data) {
    } failure:^(NSError * _Nonnull error) {
    }];
}

- (void)readNewsMessageWithaAssociationMsgId:(uint64_t)associationMsgId {
    if (associationMsgId == 0) return;
    [HJNetworking.shareNetwork POSTBodyJSON:API_readNewsMessage parameters:@{
        @"plan_id": @(associationMsgId)
    } success:^(NSDictionary * _Nonnull responseObject, id  _Nonnull data) {
    } failure:^(NSError * _Nonnull error) {
    }];
}


@end
